package com.pixpark.GPUPixelApp;

import static android.widget.Toast.LENGTH_LONG;


import static com.blankj.utilcode.util.FileUtils.getDirName;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.Toast;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.Utils;
import com.pixpark.GPUPixelApp.databinding.ActivityMainBinding;
import com.pixpark.gpupixel.GPUPixel;
import com.pixpark.gpupixel.ImageEntity;
import com.pixpark.gpupixel.filter.BeautyFaceFilter;
import com.pixpark.gpupixel.filter.FaceReshapeFilter;
import com.pixpark.gpupixel.GPUPixelSourceCamera;
import com.pixpark.gpupixel.GPUPixelView;
import com.pixpark.gpupixel.filter.LipstickFilter;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;
    private static final String TAG = "GPUPixelDemo";

    private GPUPixelSourceCamera sourceCamera;
    private GPUPixelView surfaceView;
    private BeautyFaceFilter beautyFaceFilter;  //美颜 美白  磨皮
    private FaceReshapeFilter faceReshapFilter;   //瘦脸 大眼
    private LipstickFilter lipstickFilter;  //口红
    private SeekBar smooth_seekbar;
    private SeekBar whiteness_seekbar;
    private SeekBar face_reshap_seekbar;
    private SeekBar big_eye_seekbar;
    private SeekBar lipstick_seekbar;

    private ActivityMainBinding binding;

    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        context = this;

        // get log path
        String path = getExternalFilesDir("gpupixel").getAbsolutePath();
        Log.i(TAG, path);

        GPUPixel.setContext(this);
        // 保持屏幕常亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        // preview
        surfaceView = binding.surfaceView;
        surfaceView.setMirror(true);

        smooth_seekbar = binding.smoothSeekbar;
        smooth_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                beautyFaceFilter.setSmoothLevel(progress / 10.0f);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        whiteness_seekbar = binding.whitenessSeekbar;
        whiteness_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                beautyFaceFilter.setWhiteLevel(progress / 10.0f);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });


        face_reshap_seekbar = binding.thinfaceSeekbar;
        face_reshap_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                faceReshapFilter.setThinLevel(progress / 200.0f);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        big_eye_seekbar = binding.bigeyeSeekbar;
        big_eye_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                faceReshapFilter.setBigeyeLevel(progress / 100.0f);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        lipstick_seekbar = binding.lipstickSeekbar;
        lipstick_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                lipstickFilter.setBlendLevel(progress / 10.0f);
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        //
        this.checkCameraPermission();
        this.checkExternalPermission();
        binding.takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ImageEntity imageEntity = sourceCamera.getImageShot();
                int width = imageEntity.getWidth();
                int height = imageEntity.getHeight();
                byte [] pixel = imageEntity.getImageByte();


//
//                bitmap.setPixels(argbArray, 0, width, 0, 0, width, height);
                Bitmap bitmap = convertYuvArrayToBitmap(pixel,width,height);
                imageEntity.setImageByte(null);
                pixel = null;
                Log.d(TAG,"getImageByte " + imageEntity.getRotate());
//
//                saveToLocal(bitmap,"gpuimage");
                binding.surfaceView.setVisibility(View.GONE);
                binding.imageView.setVisibility(View.VISIBLE);
                Bitmap resultBitmap = rotateBitmap(bitmap,imageEntity.getRotate());
                binding.imageView.setImageBitmap(resultBitmap);
//                binding.imageView.setImageBitmap(bitmap);
                String path = BitmapUtils.INSTANCE.saveBitmap(context,"gpuimage1.jpg",resultBitmap);
                LogUtils.d(TAG,"resultBitmap saveBitmap" + resultBitmap.getHeight() + " " + resultBitmap.getWidth());
//                String parent = PathUtils.getInternalAppCachePath() +  getDirName();
//                File file = new File(parent, "gpuimage.jpg");
//                ExifReader.readExif(file.getAbsolutePath());
//                saveToLocal(bitmap,"gpuimage");
            }
        });



    }



    public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
        Matrix matrix = new Matrix();
        Log.d(TAG,"rotateBitmap orientation=" + orientation);
        switch (orientation) {
//            case GPUPixel.NoRotation:
//                return bitmap;
            case GPUPixel.RotateLeft:  //不需要镜像
                matrix.setRotate(-90);
                break;
            case GPUPixel.RotateRight:  //不需要镜像
                matrix.setRotate(90);
                break;
            case GPUPixel.Rotate180:    //不需要镜像
                matrix.setRotate(180);
                break;
            case GPUPixel.FlipHorizontal:   // 需要镜像 水平
                matrix.setScale(-1, 1);
                break;
            case GPUPixel.RotateRightFlipVertical:  //90度  需要镜像 垂直镜像
                matrix.setRotate(90);
                matrix.postScale(1, -1);
                break;
            case GPUPixel.FlipVertical:          // 需要镜像 垂直镜像
                matrix.setRotate(180);
                matrix.postScale(1, -1);
                break;
            case GPUPixel.RotateRightFlipHorizontal:   // 需要镜像 水平镜像
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            default:
                return bitmap;
        }
        try {
            Log.d(TAG,"rotateBitmap orientationxxxx=" + orientation);
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//            Bitmap bmRotated2 = Bitmap.createBitmap(bmRotated, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix2, true);
//            bitmap.recycle();
            return bmRotated;
        }
        catch (OutOfMemoryError e) {
            e.printStackTrace();
            return null;
        }
    }

    private String getDirName() {
//        return "/" + Context.getResources().getString(R.string.app_name);
        return "/" + "GPUPixelApp";
    }

    public static Bitmap convertYuvArrayToBitmap(byte[] yuvData, int width, int height) {
        YuvImage yuvImage = new YuvImage(yuvData, ImageFormat.NV21, width, height, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, out);
        byte[] jpegData = out.toByteArray();
        Bitmap bitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
        try {
            out.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        jpegData = null;
        yuvImage = null;
        yuvData = null;
        return bitmap;
    }

    public static int rgbaToArgb(int rgba) {
        int r = (rgba >> 24) & 0xFF;
        int g = (rgba >> 16) & 0xFF;
        int b = (rgba >> 8) & 0xFF;
        int a = rgba & 0xFF;

        return (a << 24) | (r << 16) | (g << 8) | b;
    }

    private void saveToLocal(Bitmap bitmap, String bitName) {
//        String sdCardPath = Environment.getExternalStorageDirectory().getPath();
        String sdCardPath = PathUtils.getInternalAppCachePath();
        String dcimPath = sdCardPath + "/DCIM";
        File file = new File(dcimPath + "/" + bitName + ".jpg");
        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                out.flush();
                out.close();
                //保存图片后发送广播通知更新数据库
                // Uri uri = Uri.fromFile(file);
                // sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
                Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                Uri uri = Uri.fromFile(file);
                intent.setData(uri);
                this.sendBroadcast(intent);
//                showToast("保存成功");
                Log.d(TAG,"saveToLocal 保存成功");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void startCameraFilter() {
        // 美颜滤镜
        beautyFaceFilter = new BeautyFaceFilter();
        faceReshapFilter = new FaceReshapeFilter();
        lipstickFilter = new LipstickFilter();
        // camera
        sourceCamera = new GPUPixelSourceCamera(this.getApplicationContext());

        //
        sourceCamera.addTarget(lipstickFilter);
        lipstickFilter.addTarget(faceReshapFilter);
        faceReshapFilter.addTarget(beautyFaceFilter);
        beautyFaceFilter.addTarget(surfaceView);

        sourceCamera.setLandmarkCallbck(new GPUPixel.GPUPixelLandmarkCallback() {
            @Override
            public void onFaceLandmark(float[] landmarks) {
                faceReshapFilter.setFaceLandmark(landmarks);
                lipstickFilter.setFaceLandmark(landmarks);
            }
        });
        // set default value
        beautyFaceFilter.setSmoothLevel(0.5f);
        beautyFaceFilter.setWhiteLevel(0.4f);
    }

    public void checkCameraPermission() {
        // 检查相机权限是否已授予
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // 如果未授予相机权限，向用户请求权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
        } else {
            startCameraFilter();
        }
    }

    public void checkExternalPermission() {
        // 检查相机权限是否已授予
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.MANAGE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 如果未授予相机权限，向用户请求权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.MANAGE_EXTERNAL_STORAGE}, CAMERA_PERMISSION_REQUEST_CODE);
        } else {
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCameraFilter();
            } else {
                Toast.makeText(this, "No Camera permission!", LENGTH_LONG);
            }
        }
    }


    public void surfaceCreated(SurfaceHolder holder) {
        sourceCamera.setPreviewHolder(holder);
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }
}